﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Framework.Core;
using Yoozoo.Managers;

namespace Gameplay.PVE.Survivor
{
    public class BattlePoolManager: BattleSingleton<BattlePoolManager>
    {
        public Transform Root;
        
        private Dictionary<int,GameObjectPool<BattleGameObject>> poolDic = new Dictionary<int, GameObjectPool<BattleGameObject>>();
        private Dictionary<int,GameObjectPool<BattleEffectObject>> effectDic = new Dictionary<int, GameObjectPool<BattleEffectObject>>();
        private Dictionary<int,GameObjectPool<BattleFlyTextObject>> flyTextDic = new Dictionary<int, GameObjectPool<BattleFlyTextObject>>();
        private Dictionary<int,GameObjectPool<BattleHudObject>> hudDic = new Dictionary<int, GameObjectPool<BattleHudObject>>();
        
        public void Initialize()
        {
            Root = new GameObject("[BattlePool]").transform;
            Root.transform.parent = SurvivorManager.Instance.Root;
        }
        
        public BattleGameObject Get(EBattleResId resId, Action<GameObject> callback = null)
        {
            return Get((int)resId, callback);
        }
        
        public BattleGameObject Get(string path, Action<GameObject> callback = null)
        {
            var gameObject = new BattleGameObject();
            gameObject.Create(path, callback);
            return gameObject;
        }

        public void Release<T>(Dictionary<int,GameObjectPool<T>> dic,T gameObject) where T : BattleGameObject
        {
            var resId = gameObject.resId;
            if (dic.TryGetValue(resId, out var pool))
            {
                pool.Release(gameObject);
            }
            else
            {
                //BattleDebug.LogError("没有找到对应的资源池 " + resId);
                gameObject.Dispose();
            }
        }
        
        public BattleFlyTextObject GetFlyText(int resId, Action<GameObject> callback = null)
        {
            return Get(flyTextDic,resId, callback);
        }
        
        public void ReleaseFlyText(BattleFlyTextObject gameObject)
        {
            Release(flyTextDic,gameObject);
        }
        
        public BattleEffectObject GetEffect(int resId, Action<GameObject> callback = null)
        {
            var effect = Get(effectDic,resId, callback);
            if (effect == null)
            {
                return emptyEffectObject;
            }
            return effect;
        }
        
        public void ReleaseEffect(BattleEffectObject gameObject)
        {
            Release(effectDic,gameObject);
        }
        
        public BattleHudObject GetHud(int resId, Action<GameObject> callback = null)
        {
            return Get(hudDic,resId, callback);
        }
        
        public void ReleaseHud(BattleHudObject gameObject)
        {
            Release(hudDic,gameObject);
        }

        public BattleGameObject Get(int resId, Action<GameObject> callback = null)
        {
            return Get(poolDic,resId, callback);
        }
        
        public void Release(BattleGameObject gameObject)
        {
            Release(poolDic,gameObject);
        }
        
        public T Get<T>(Dictionary<int,GameObjectPool<T>> poolDic,int resId, Action<GameObject> callback = null) where T : BattleGameObject
        {
            if (!poolDic.TryGetValue(resId, out var pool))
            {
                var resourceConfig = BattleConfigManager.Instance.GetResourceConfig(resId);
                if (resourceConfig == null)
                {
                    return BattlePoolManager.emptyGameObject as T;
                }

                pool = new GameObjectPool<T>();
                pool.Initialize(resId, resourceConfig.path + ".prefab", resourceConfig.poolNum);
                poolDic.Add(resId, pool);
            }

            var gameObject = pool.Get();
            if (callback != null)
            {
                gameObject.SetPrefabReadyAction(callback);
            }

            if (gameObject.IsReady)
            {
                gameObject.OnUsed();
            }
            return gameObject;
        }
        
        private static BattleGameObject emptyGameObject = new BattleGameObject();
        private static BattleEffectObject emptyEffectObject = new BattleEffectObject();
        private static BattleFlyTextObject emptyFlyTextObject = new BattleFlyTextObject();
        private static BattleHudObject emptyHudObject = new BattleHudObject();

        public override void Dispose()
        {
            foreach (var pool in poolDic)
            {
                pool.Value.Dispose();
            }
            poolDic.Clear();
            foreach (var pool in effectDic)
            {
                pool.Value.Dispose();
            }
            effectDic.Clear();
            foreach (var pool in flyTextDic)
            {
                pool.Value.Dispose();
            }
            flyTextDic.Clear();
            foreach (var pool in hudDic)
            {
                pool.Value.Dispose();
            }
            hudDic.Clear();
        }
    }
}
